package crew.blt.handsound.client.webgl;

import java.util.Collection;
import java.util.Iterator;

import com.google.gwt.core.client.JavaScriptException;

import crew.blt.handsound.client.webgl.property.Property;

public class SceneJSUtil {

	/**
	 * Read the value in the JSON graph then cast and return it.
	 * @param <T> cast's type
	 * @param fromElementId Element's id where read the property value
	 * @param property
	 * @return the value as set into SceneJS
	 */
//	public static <T> T readPropertyValue(String fromElementId,Property<T,?> property){
//		return (T) nativeReadValueIntoJSONTree(fromElementId, property.getPropertyName());
//	}
	
//	public static native <T> T readPropertyValue(String fromElementId,Property<T,?> property) /*-{
//		return $wnd.SceneJS.withNode(fromElementId).get(property.@crew.blt.handsound.client.webgl.property.Property::getPropertyName());
//	}-*/;
	
	public static native <T> T readPropertyValue(String fromElementId,Property<T,?> property) throws JavaScriptException /*-{
		var propertyName = property.@crew.blt.handsound.client.webgl.property.Property::getPropertyName()();
		var propertyValue = $wnd.SceneJS.withNode(fromElementId).get(propertyName);
		if( typeof(propertyValue) == "number" ) {
			return @java.lang.Float::valueOf(F)(propertyValue);
		}
		else if( typeof(propertyValue) == "string" ) {
			return @java.lang.String::new(Ljava/lang/String;)(propertyValue);
		}
		else if( typeof(propertyValue) == "boolean" ) {
			return @java.lang.Boolean::valueOf(Z)(propertyValue);
		}
		return null;
	}-*/; 
	
	private static native Object nativeReadValueIntoJSONTree(String elementId,String property) /*-{ 
        return $wnd.SceneJS.withNode(elementId).get(property);
    }-*/; 

	/**
	 * Write the value into the JSON graph.
	 * @param id the node id
	 * @param property
	 * @param value
	 */
	public static native void writePropertyValue(String elementId,String property,String value) /*-{ 
        $wnd.SceneJS.withNode(elementId).set(property, value);
    }-*/; 
	
	
	public static native void insertElementIntoNode(String elementJSONString, String parentNodeId) /*-{ 
        $wnd.SceneJS.withNode(parentNodeId).add("node", elementJSONString);
    }-*/; 
	

	/**
	 * Construct a String which represent the list of property into a JSON format.
	 * 
	 *	" x:1, y:1, z:1"
	 * 
	 * @param properties to list in the String
	 * @return the constructed String
	 */
	public static String createJSONPropertiesString(Collection<Property<?,?>> properties){
		String propertiesString = " ";
		String delimiter = ", ";
		Iterator<Property<?,?>> iterator = properties.iterator();
		boolean hasNext = iterator.hasNext();
		while( hasNext ) {
			// if another property follow, add a delimiter
			propertiesString += iterator.next().getJSONString() +
								( (hasNext=iterator.hasNext()) ? "" : delimiter ); 
		}
		return propertiesString;
	}
}
